package com.syh.jn.scm.infrastructure.repository.impl.supplier.stock;

import cn.redscarf.commons.util.other.ExtStringUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AggregateRepoMybatisImplTmpl;
import com.syh.jn.scm.domain.supplier.entity.stock.StockRecord;
import com.syh.jn.scm.domain.supplier.repository.stock.StockRecordReadRepository;
import com.syh.jn.scm.dto.supplier.stock.StockRecordItemVo;
import com.syh.jn.scm.dto.supplier.stock.StockRecordVo;
import com.syh.jn.scm.infrastructure.repository.model.base.StorehouseModel;
import com.syh.jn.scm.infrastructure.repository.model.stock.StockRecordItemModel;
import com.syh.jn.scm.infrastructure.repository.model.stock.StockRecordModel;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import lombok.extern.java.Log;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;


/**
 * 出入库记录
 */

@Log
@Repository("stockRecordReadRepositoryMbImpl")
public class StockRecordReadRepositoryMbImpl implements StockRecordReadRepository {

  private AggregateRepoMybatisImplTmpl<StockRecordVo, StockRecordModel, Long> stockRecordRepoMybatisImplTmpl =
          new AggregateRepoMybatisImplTmpl.Builder().listTypeClass(StockRecordVo.class).modelClass(StockRecordModel.class).build();
  private AggregateRepoMybatisImplTmpl<StockRecordItemVo, StockRecordItemModel, Long> stockRecordItemsRepoMybatisImplTmpl =
          new AggregateRepoMybatisImplTmpl.Builder().listTypeClass(StockRecordItemVo.class).modelClass(StockRecordItemModel.class).build();


  /**
   * 一般使用orm框架实现 例如Hibenate 根据主键获取数据
   *
   * @param aLong
   * @return
   */
  @Override
  public StockRecordVo getById(Long aLong) {
    return stockRecordRepoMybatisImplTmpl.getById(aLong);
  }

  /**
   * @param wrapper
   * @return
   */
  @Override
  public StockRecordVo getOne(Wrapper wrapper) {
    StockRecordVo vo = stockRecordRepoMybatisImplTmpl.getOne(wrapper);
    if (vo != null) {
      vo.setItemsVo(this.findStockRecordItemsByStockRecordId(vo.getId()));
    }
    return vo;
  }

  /**
   * 一般使用orm框架实现 例如Hibenate 根据条件获取数据
   *
   * @param aLong
   * @return
   */
  @Override
  public boolean contains(Long aLong) {
    return stockRecordRepoMybatisImplTmpl.contains(aLong);
  }

  /**
   * 一般使用orm框架实现 例如Hibenate 根据条件获取数据
   *
   * @param wrapper
   * @return
   */
  @Override
  public List<StockRecordVo> getList(Wrapper wrapper) {
    return stockRecordRepoMybatisImplTmpl.getList(wrapper);
  }

  /**
   * 一般使用orm框架实现 例如Hibenate 根据条件获取数据
   *
   * @param wrapper
   * @param startRow
   * @param count
   * @return
   */
  @Override
  public List<StockRecordVo> findListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return stockRecordRepoMybatisImplTmpl.findListPage(wrapper, startRow, count);
  }

  /**
   * 一般使用orm框架实现 例如Hibenate 获取数量
   *
   * @param wrapper
   * @return
   */
  @Override
  public int getCount(Wrapper wrapper) {
    return stockRecordRepoMybatisImplTmpl.getCount(wrapper);
  }

  /**
   * 根据出入库记录id获取出入库记录项
   *
   * @param stockRecordId
   * @return
   */
  @Override
  public List<StockRecordItemVo> findStockRecordItemsByStockRecordId(Long stockRecordId) {
    Wrapper wrapper = Wrapper.build().append(Restrictions.eq("recordOrderId", stockRecordId));
    return this.stockRecordItemsRepoMybatisImplTmpl.getList(wrapper);
  }


  /**
   * 根据出入库记录id获取出入库记录项
   *
   * @param wrapper
   * @param startRow
   * @param count
   * @return
   */
  @Override
  public List<StockRecordItemVo> findStockRecordItemListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return stockRecordItemsRepoMybatisImplTmpl.findListPage(wrapper, startRow, count);
  }

  /**
   * 根据出入库记录id获取出入库记录项数量
   *
   * @param wrapper
   * @return
   */
  @Override
  public int findStockRecordItemListPageCount(Wrapper wrapper) {
    return stockRecordItemsRepoMybatisImplTmpl.getCount(wrapper);
  }

  @Override
  public boolean stockRecordItemExistsById(String column, Long id) {
    Wrapper wrapper = Wrapper.build().append(Restrictions.eq(column, id));
    return this.stockRecordItemsRepoMybatisImplTmpl.getOne(wrapper) != null;
  }


  @Override
  public StockRecord getByLogisticsBillId(Long bllId) {
    log.warning("该接口暂不实现");
    return null;
  }

  public StockRecordReadRepositoryMbImpl() {
    // 初始化查询语句 stockRecord
    SQL stockRecordSql = new SQL() {{
      SELECT(
              SQLAliasGenerateUtil.aliasGenerate(new Class[]{StockRecordModel.class, StorehouseModel.class},
                      new String[]{"record", "storehouse"}, null),
              "storehouse.NAME AS storehouseName"
      );
      FROM("T_STOCK_STOCK_RECORD record");
      LEFT_OUTER_JOIN(
              "T_BASE_STOREHOUSE storehouse on record.STOREHOUSE_ID = storehouse.ID"
      );
    }};
    this.stockRecordRepoMybatisImplTmpl.setQuerySql(stockRecordSql);
    //初始化查询条件解析 stockRecord
    final HashMap<String, String> weMap = new HashMap<>();
    weMap.put("id", "record.ID");
    weMap.put("originalOrderCode", "record.ORIGINAL_ORDER_CODE");
    weMap.put("recordOrderCode", "record.RECORD_ORDER_CODE");
    weMap.put("supId", "record.SUP_ID");
    weMap.put("type", "record.TYPE");
    weMap.put("storehouseId", "record.STOREHOUSE_ID");
    weMap.put("businessEntityId", "record.BUSINESS_ENTITY_ID");
    weMap.put("createTimeStamp", "record.CREATE_TIME_STAMP");
    this.stockRecordRepoMybatisImplTmpl.setWrapperParseMethods((propertyName) -> {
      return weMap.get(propertyName);
    });

    // stockRecordItem
    String stockRecordTable = this.stockRecordRepoMybatisImplTmpl.getModelTableName(StockRecordModel.class);
    String stockRecordItemTable = this.stockRecordRepoMybatisImplTmpl.getModelTableName(StockRecordItemModel.class);
    String storehouseTable = this.stockRecordRepoMybatisImplTmpl.getModelTableName(StorehouseModel.class);
    SQL stockRecordItemSql = new SQL() {{
      SELECT(
              SQLAliasGenerateUtil.aliasGenerate(StockRecordItemModel.class, "recordItem", null),
              "stockRecord.TYPE as type",
              "stockRecord.STOREHOUSE_ID as storehouseId",
              "stockRecord.CREATE_TIME_STAMP as createTimeStamp",
              "storehouse.NAME as storehouseName",
              "stockRecord.ORIGINAL_ORDER_CODE as originalOrderCode",
              "stockRecord.RECORD_ORDER_CODE as recordOrderCode"
      );
      FROM(
              ExtStringUtils.buildString(stockRecordItemTable, " recordItem")
      );
      INNER_JOIN(
              ExtStringUtils.buildString(stockRecordTable, " stockRecord on recordItem.RECORD_ORDER_ID = stockRecord.ID")
      );
      LEFT_OUTER_JOIN(
              ExtStringUtils.buildString(storehouseTable + " storehouse on stockRecord.STOREHOUSE_ID = storehouse.ID")
      );
    }};
    this.stockRecordItemsRepoMybatisImplTmpl.setQuerySql(stockRecordItemSql);
    //初始化查询条件解析 stockRecordItem
    final HashMap<String, String> stockRecordItemMap = new HashMap<>();
    stockRecordItemMap.put("id", "stockRecord.ID");
    stockRecordItemMap.put("originalOrderId", "stockRecord.ORIGINAL_ORDER_ID");
    stockRecordItemMap.put("originalOrderCode", "stockRecord.ORIGINAL_ORDER_CODE");
    stockRecordItemMap.put("originalLogisticsId", "stockRecord.ORIGINAL_LOGISTICS_ID");
    stockRecordItemMap.put("recordOrderCode", "stockRecord.RECORD_ORDER_CODE");
    stockRecordItemMap.put("supId", "stockRecord.SUP_ID");
    stockRecordItemMap.put("type", "stockRecord.TYPE");
    stockRecordItemMap.put("dataType", "stockRecord.DATA_TYPE");
    stockRecordItemMap.put("storehouseId", "stockRecord.STOREHOUSE_ID");
    stockRecordItemMap.put("goodsId", "recordItem.GOODS_ID");
    stockRecordItemMap.put("orderItemId", "recordItem.ORDER_ITEM_ID");
    stockRecordItemMap.put("businessEntityId", "stockRecord.BUSINESS_ENTITY_ID");
    stockRecordItemMap.put("createTimeStamp", "stockRecord.CREATE_TIME_STAMP");
    stockRecordItemMap.put("recordTimeStamp", "stockRecord.RECORD_TIME_STAMP");
    this.stockRecordItemsRepoMybatisImplTmpl.setWrapperParseMethods((propertyName) -> {
      return stockRecordItemMap.get(propertyName);
    });


  }


}
